#include <cstdio>
#include <list>
#include "snake_define.h"
#include "food_define.h"
#include "map_build.h"


extern std::list<FoodNode> food_list;
extern std::list<Snake> snake_list;

extern Map global_map;

/*总体思路*/
//1. 从当前蛇取出蛇的头节点来，新建一个新的头结点，以旧的头结点初始化之
//2. 根据这个头结点的方向，改变其x,y值
//3. 然后讲这个新的头结点重新插入到蛇头的位置上去
//4. 判断吃没吃到食物，如果没有吃到食物，将蛇尾从蛇的数据结构中删除
//5. 否则（吃到食物，则蛇尾不删去）
void Snake::snake_move()
{
    //S1:
    //SnakeNode temp_head = temp_snake.get_snake_head();//此函数返回头结点的引用
    SnakeNode &temp_head = m_snake.front();//此函数返回头结点的引用
    SnakeNode new_head(temp_head);

    //S2:
    switch(temp_head.dir) //判断当前蛇头方向
    {
        case UP:
            new_head.y --;
            if(new_head.y <= 0)
            {
                new_head.y = 80;
            }
            printf("Snake 上\n");
            break;
        case DOWN:
            new_head.y ++;
            if(new_head.y >= 80)
            {
                new_head.y = 0;
            }
            printf("Snake 下\n");
            break;
        case LEFT:
            new_head.x --;
            if(new_head.x <=0)
            {
                new_head.x = 80;
            }
            printf("Snake 左\n");
            break;
        case RIGHT:
            new_head.x ++;
            if(new_head.x >=80)
            {
                new_head.x = 0;
            }
            printf("Snake 右\t");
            break;
        case NONE_DIR://测试用
            printf("this snake is none dir\n");
            break;
    }
    //S3:将新蛇头重新插入到蛇中
    //temp_snake.renew_snake_head(temp_head);
    printf("head's pos[%d,%d]\t", new_head.x, new_head.y);
    m_snake.push_front(new_head);

    //先检查游戏是否有必要继续进行
    check_hit_self();
    check_hit_other();
    if(isGameOver())//如果游戏已经结束了
    {
        //清理工作已经由check()完成
        return;//直接返回
    }

    //S4:
    //if(!this->isEatFood())
    if(!isEatFood())//如果没有吃到食物，就移除尾巴；否则不移除尾巴
    {
        this->remove_snake_tail();
    }
    
    printf("tail's pos[%d,%d]\n", m_snake.back().x, m_snake.back().y);
}

bool Snake::isEatFood()
{
    SnakeNode temp_head = this->get_snake_head();
    for(FoodNode &temp_food : food_list)
    {
        //if((temp_food.x == temp_head.x)&& (temp_food.y == temp_head.y))
        if((temp_food.get_x() == temp_head.x)&& (temp_food.get_y() == temp_head.y))
        {
            //当前当前蛇的成绩增加
            add_user_score();
            //那么再 food_list 中也应该将这个食物删除
            food_list.remove(temp_food);
            return true;
        }
    }
    return false;
}


void Snake::remove_snake_tail()
{
    //SnakeNode temp_tail = m_snake.front();//队列头是蛇尾巴
    SnakeNode temp_tail = m_snake.back();//队列头是蛇尾巴
    
    //global_map.m_map[temp_tail.x][temp_tail.y] = mapColorOne;//Map 的m_map成员是私有的，增加以下方法以解决
    global_map.renew_to_mapcolor(temp_tail.x, temp_tail.y);

    //m_snake.pop();//将蛇尾去掉
    m_snake.pop_back();
}

void Snake::snake_die()
{
    for(auto siter=m_snake.begin(); siter!= m_snake.end(); siter++)
    {
        global_map.renew_to_mapcolor(siter->x, siter->y);
    }
}


/*
*创建蛇的时候，检查以下蛇是否是有效的一条蛇,如果有效，返回true,反之为false
*/
bool Snake::check_birth_valid()
{
    if(snake_list.empty())
    {
        return true;
    }

    //对每一节蛇身进行检查
    for(auto biter=get_snake_total().begin(); biter!=get_snake_total().end(); biter++)
    {
        for(auto siter=snake_list.begin();siter!=snake_list.end(); siter++)
        {
            for(auto sbiter=siter->get_snake_total().begin(); sbiter!=siter->get_snake_total().end(); sbiter++)
            {
                if((sbiter->x ==biter->x)&&(sbiter->y == biter->y))
                {
                    return false;
                }
            }
        }
    }
    return true;

}
